package com.lj.message.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.lj.common_web.response.ResponseVO;
import com.lj.message.entity.SysMessage;
import com.lj.message.mapper.SysMessageMapper;
import com.lj.message.param.SysMessageSaveParam;
import com.lj.message.result.SysMessageInfoResult;
import com.lj.message.service.SysMessageService;
import com.lj.mp.standard.StandardServiceImpl;
import com.lj.sse.service.SseService;
import com.lj.sse.utils.SseContextUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 系统消息表 服务实现类
 * </p>
 *
 * @author luojing
 * @since 2025-10-15 16:57:29
 */
@Service
@Slf4j
public class SysMessageServiceImpl extends StandardServiceImpl<SysMessageMapper, SysMessage> implements SysMessageService {

    @Resource
    private SseService sseService;

    @Override
    public SseEmitter open(String clientId) {
        final long userId = StpUtil.getLoginIdAsLong();
        // 心跳间隔
        SseEmitter sseEmitter = sseService.createSseConnect(clientId, 5, TimeUnit.SECONDS,
                sseRecord -> SseContextUtils.send(sseRecord, ResponseVO.success(sseRecord.getClientId())));
        // 发送一次消息列表
        this.asyncSendMessage(userId);
        return sseEmitter;
    }

    @Override
    public void sendMessage(SysMessageSaveParam param) {
        this.save(param);
        // 发送消息
        this.asyncSendMessage(param.getTargetId());
    }

    private void asyncSendMessage(Long userId) {
        ThreadUtil.execute(() -> {
            List<SysMessageInfoResult> userMessageList = getUserMessageList(userId);
            SseContextUtils.send(userId, ResponseVO.success(userMessageList));
        });
    }

    private List<SysMessageInfoResult> getUserMessageList(Long userId) {
        return list(lambdaQueryWrapper()
                .eq(SysMessage::getTargetId, userId)
                .orderByDesc(SysMessage::getCreateTime))
                .stream().map(SysMessageInfoResult::of).toList();
    }

    @Override
    public void save(SysMessageSaveParam param) {
        SysMessage entity = param.toEntity();
        this.save(entity);
    }

    @Override
    public void delete(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        long userId = StpUtil.getLoginIdAsLong();
        remove(lambdaQueryWrapper()
                .eq(SysMessage::getTargetId, userId)
                .eq(ids.size() == 1, SysMessage::getId, ids.get(0))
                .in(ids.size() > 1, SysMessage::getId, ids));
        this.asyncSendMessage(userId);
    }

    @Override
    public void markRead(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        long userId = StpUtil.getLoginIdAsLong();
        update(lambdaUpdateWrapper()
                .set(SysMessage::getMarkRead, true)
                .eq(SysMessage::getTargetId, userId)
                .eq(ids.size() == 1, SysMessage::getId, ids.get(0))
                .in(ids.size() > 1, SysMessage::getId, ids));
        this.asyncSendMessage(userId);
    }
}
